﻿#region Copyright ©2008-2009, Technische Universitaet Muenchen
// ====================================================================================================
//
// Last Changed by       $Author: then $
// Last Changed Date     $LastChangedDate: 2009-05-16 14:58:56 +0200 (Sat, 16 May 2009) $
// Last Changed Revision $Rev: 144 $
//
// ====================================================================================================
#endregion

using System;
using System.Collections.Generic;
using System.Xml;
using Tum.CollabXT.TFS.Resources;

namespace Tum.CollabXT.TFS
{
    class Classification : IProcessor
    {
        string[] IterationPaths;

        public Classification(string[] iterationPaths)
        {
            this.IterationPaths = iterationPaths;
        }

        public void Process(IProcessProvider processProvider, TFSToolProvider toolProvider)
        {
            toolProvider.ProcessLog.AddEntry(Language.Classification_IterationPathTree);
            IterationPathTreeNode iterationPathTree = BuildIterationPathTree();

            string classificationTemplateFileName = toolProvider.OutputPath + "/Classification/Classification.xml";

            #region Load template
            XmlDocument classificationDoc = new XmlDocument();
            toolProvider.ProcessLog.AddEntry(Language.Classification_Loading);
            try
            {
                classificationDoc.Load(classificationTemplateFileName);
            }
            catch
            {
                toolProvider.ProcessLog.AddEntryAndThrowException(string.Format(Language.Error_LoadingFailed, classificationTemplateFileName));
            }
            #endregion

            toolProvider.ProcessLog.AddEntry(Language.Classification_SelectingLifecycleNode);
            var defaultLifeCycleNode = classificationDoc.SelectSingleNode("/tasks/task/taskXml/Nodes/Node[@StructureType=\"ProjectLifecycle\"]/Children");
            if (defaultLifeCycleNode == null)
                toolProvider.ProcessLog.AddEntryAndThrowException(Language.Error_NotFound_InvalidTemplate);

            //Write iteration path tree
            foreach (IterationPathTreeNode curTreeChild in iterationPathTree.Children)
            {
                WriteIterationPathNode(curTreeChild, defaultLifeCycleNode);
            }

            #region Save classification file
            toolProvider.ProcessLog.AddEntry(Language.Classification_Saving);
            try
            {
                classificationDoc.Save(classificationTemplateFileName);
            }
            catch
            {
                toolProvider.ProcessLog.AddEntryAndThrowException(string.Format(Language.Error_SavingFailed, classificationTemplateFileName));
            }
            #endregion
        }

        private void WriteIterationPathNode(IterationPathTreeNode iterationPathNodeToWrite, XmlNode parentXmlNode)
        {
            XmlNode lifeCycleNode = parentXmlNode.OwnerDocument.CreateNode("element", "Node", "");
            XmlAttribute structureTypeAttribute = parentXmlNode.OwnerDocument.CreateAttribute("StructureType");
            structureTypeAttribute.Value = "ProjectLifecycle";
            lifeCycleNode.Attributes.Append(structureTypeAttribute);
            XmlAttribute nameAttribute = parentXmlNode.OwnerDocument.CreateAttribute("Name");
            nameAttribute.Value = iterationPathNodeToWrite.NodeName;
            lifeCycleNode.Attributes.Append(nameAttribute);

            if (iterationPathNodeToWrite.Children.Count > 0)
            {
                //Node has children -> Recursive completion
                XmlNode childrenNode = parentXmlNode.OwnerDocument.CreateNode("element", "Children", "");

                foreach (IterationPathTreeNode curChild in iterationPathNodeToWrite.Children)
                {
                    WriteIterationPathNode(curChild, childrenNode);
                }
                lifeCycleNode.AppendChild(childrenNode);
            }

            parentXmlNode.AppendChild(lifeCycleNode);
        }

        private IterationPathTreeNode BuildIterationPathTree()
        {
            if (IterationPaths == null)
                throw new TFSException("IterationPaths must not be null.");

            IterationPathTreeNode root = new IterationPathTreeNode("_");
            char[] splitter = new char[] { '\\' };

            foreach (string curIterationPath in IterationPaths)
            {
                string[] splittedIterationPath = curIterationPath.Split(splitter, StringSplitOptions.RemoveEmptyEntries);
                IterationPathTreeNode curIterationNode = root;

                foreach (string curPathPart in splittedIterationPath)
                {
                    curIterationNode = curIterationNode.FindChildNode(curPathPart);
                }
            }

            return root;
        }


        private class IterationPathTreeNode
        {
            public string NodeName
            {
                get { return _NodeName; }
            }
            string _NodeName;

            public List<IterationPathTreeNode> Children = new List<IterationPathTreeNode>();

            public IterationPathTreeNode(string nodeName)
            {
                _NodeName = nodeName;
            }

            public IterationPathTreeNode FindChildNode(string name)
            {
                foreach (IterationPathTreeNode curChild in Children)
                {
                    if (curChild.NodeName.Equals(name, StringComparison.OrdinalIgnoreCase))
                        return curChild;
                }
                IterationPathTreeNode newChild = new IterationPathTreeNode(name);
                Children.Add(newChild);
                return newChild;
            }
        }
    }
}
